package cn.edu.cuit.elena.web.tool;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import cn.edu.cuit.elena.common.SackConstants;
import cn.edu.cuit.elena.db.DataSource;
import cn.edu.cuit.elena.db.Schema.Column;
import cn.edu.cuit.elena.db.Schema.Table;

import com.google.gson.Gson;

public class JsonHelper
{
    private Gson gson;

    private JsonHelper()
    {
        gson = new Gson();
    }

    public static JsonHelper getNewInstance()
    {
        return new JsonHelper();
    }

    public <T> String toJson( Iterable<T> iterable )
    {
        return gson.toJson( iterable );
    }

  
    public String toJson( Object o )
    {
        return gson.toJson( o );
    }

    public <T> String toJson( Iterable<T> iterable, Class<T> tClass )
    {
        return gson.toJson( iterable, tClass );
    }

    /**
     * <pre>
     *          Iterable{
     *                      DataSource1,
     *                      DataSource2,
     *                      ...
     *                  }
     * </pre>
     * */
    public String toDataSourcesJson( Iterable<DataSource> iterable )
    {
        LinkedList<Map<String, String>> list = new LinkedList<Map<String, String>>();
        for( DataSource dataSource : iterable )
        {
            String driver = dataSource.getDriver() == null ? "" : dataSource.getDriver();
            String schemaname = dataSource.getName() == null ? "" : dataSource.getName();
            String password = dataSource.getPassWord() == null ? "" : dataSource.getPassWord();
            String username = dataSource.getUserName() == null ? "" : dataSource.getUserName();
            String url = dataSource.getUrl() == null ? "" : dataSource.getUrl();
            String state = dataSource.getState() == null ? "" : dataSource.getState();
            String vender = dataSource.getVender() == null ? "" : dataSource.getVender();
            String datasourceId = dataSource.getDatasourceId() == null ? "" : dataSource.getDatasourceId();
            Map<String, String> map = new HashMap<String, String>();
            map.put( SackConstants.DRIVER, driver );
            map.put( SackConstants.SCHEMA_NAME, schemaname );
            map.put( SackConstants.PASS_WORD, password );
            map.put( SackConstants.USER_NAME, username );
            map.put( SackConstants.URL, url );
            map.put( SackConstants.DATASOURCE_STATE, state );
            map.put( SackConstants.VENDER, vender );
            map.put( SackConstants.DATASOURCE_ID, datasourceId );

            list.add( map );
        }

        return gson.toJson( list );
    }

    public <K, V> String toJson( Map<K, V> map )
    {
        return gson.toJson( map );
    }

    public String toUserGroupTree( List<Map<String, String>> data )
    {
        Map<String, LinkedList<Map<String, Map<String, String>>>> tree = new HashMap<String, LinkedList<Map<String, Map<String, String>>>>();
        /**
         * <pre>
         * Map tree{ 
         *          root:List[ 
         *                  Map_1->node_1 Map_2->node_2 
         *                  ]
         *           }
         * </pre>
         * */

        LinkedList<Map<String, Map<String, String>>> children = new LinkedList<Map<String, Map<String, String>>>();
        tree.put( "root", children );

        LinkedList<String> tmp = new LinkedList<String>();

        for( Map<String, String> row : data )
        {
            String usergroup = row.get( "usergroup" );
            String username = row.get( "username" );
            String gender = row.get( "gender" );

            Map<String, List<Map<String, String>>> node;
            if( !tmp.contains( usergroup ) )
            {
                node = new HashMap<String, List<Map<String, String>>>();
                LinkedList<Map<String, String>> nodeList = new LinkedList<Map<String, String>>();
                tmp.add( usergroup );
                node.put( usergroup, null );
                Map<String, String> nodeContent = new HashMap<String, String>();
                nodeContent.put( "usergroup", usergroup );
                nodeContent.put( "username", username );
                nodeContent.put( "gender", gender );
                nodeList.add( nodeContent );
            }
            //            else
            //            {
            //                node.get( usergroup )
            //
            //            }
        }
        return null;
    }

    public String toTablesJson( Map<String, Table> tables )
    {
        LinkedList<Map<String, String>> list = new LinkedList<Map<String, String>>();
        for( Map.Entry<String, Table> entry : tables.entrySet() )
        {
            Table table = entry.getValue();
            Map<String, String> temp = new HashMap<String, String>();
            temp.put( "hdfspath", table.getHdfsPath() );
            temp.put( "hivetablename", table.getHiveTableName() );
            temp.put( "tablename", table.getName() );
            temp.put( "columncount", table.getColumnCount() );
            temp.put( "rowcount", table.getRowCount() );
            temp.put( "schemaname", table.getSchema().getName() );

            list.add( temp );
        }

        return gson.toJson( list );
    }

    public String toColumnJson( Table table )
    {
        List<Map<String, String>> list = new LinkedList<Map<String, String>>();

        for( Entry<String, Column> entry : table.getColumns().entrySet() )
        {
            String columnName = entry.getKey();
            Column column = entry.getValue();

            String pk = String.valueOf( column.isPK() );
            String fk = String.valueOf( column.isFK() );

            Map<String, String> map = new HashMap<String, String>();
            map.put( "columnname", columnName );
            map.put( "pk", pk );
            map.put( "fk", fk );

            list.add( map );
        }

        return gson.toJson( list );
    }
}
